package com.laiketui.order.service.wechatPay.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.laiketui.common.api.openUser.OpenUserService;
import com.laiketui.common.config.wechatpay.WechatConfigInfo;
import com.laiketui.common.mapper.*;
import com.laiketui.common.utils.pay.WechatPayUtils;
import com.laiketui.common.utils.tool.cache.RedisDataTool;
import com.laiketui.common.utils.weixin.XmlUtil;
import com.laiketui.core.cache.RedisUtil;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.core.lktconst.GloabConst;
import com.laiketui.core.utils.help.SpringHelper;
import com.laiketui.core.utils.tool.DataUtils;
import com.laiketui.core.utils.tool.IpUtil;
import com.laiketui.domain.lktconst.ErrorCode;
import com.laiketui.domain.user.User;
import com.laiketui.order.api.enums.OrderParentMessageType;
import com.laiketui.order.api.enums.OrderParentStatusEnum;
import com.laiketui.order.api.enums.PayTypeEnum;
import com.laiketui.order.api.params.wechatPay.PaymentParams;
import com.laiketui.order.common.AppConst;
import com.laiketui.order.domain.OrderParent;
import com.laiketui.order.mapper.OrderParentMapper;
import com.laiketui.order.service.OrderParentMessageService;
import com.laiketui.order.service.OrderParentService;
import com.laiketui.order.service.pay.impl.BalancePayServiceImpl;

import com.laiketui.order.service.wechatPay.WechatPayService;
import com.laiketui.root.annotation.DubboApiMethod;
import github.wxpay.sdk.WXPay;
import github.wxpay.sdk.WXPayConstants;
import github.wxpay.sdk.WXPayUtil;
import io.minio.Xml;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.dom4j.DocumentFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xmlunit.util.Convert;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.laiketui.domain.lktconst.DictionaryConst.OrderPayType.*;
import static com.laiketui.domain.lktconst.ErrorCode.BizErrorCode.*;

@Service
public class WechatPayServiceImpl implements WechatPayService {

    private final Logger logger = LoggerFactory.getLogger(WechatPayServiceImpl.class);

    @Autowired
    private UserMapper userMapper;

//    @Autowired
//    private RedisUtil redisUtil;

    @Autowired
    private PaymentConfigModelMapper paymentConfigModelMapper;

    @Autowired
    private OrderModelMapper orderModelMapper;

    @Autowired
    private OrderDetailsModelMapper orderDetailsModelMapper;

    @Autowired
    private OrderDataModelMapper orderDataModelMapper;

//    @Autowired
//    private PublicOrderService publicOrderService;

    @Autowired
    private ConfigModelMapper configModelMapper;

    @Autowired
    private NoticeModelMapper noticeModelMapper;

    @Autowired
    private PreSellRecordModelMapper preSellRecordModelMapper;

    @Autowired
    private PreSellGoodsMapper preSellGoodsMapper;

    @Autowired
    private UserBaseMapper userBaseMapper;

    @Autowired
    private OrderParentMapper orderParentMapper;

    @Autowired
    private OrderParentMessageService orderParentMessageService;

    @Autowired
    private OrderParentService orderParentService;

    @Autowired
    private OpenUserService openUserService;



    /**
     * 微信支付V2
     *
     * @param params
     * @return
     * @throws LaiKeAPIException
     */
    @DubboApiMethod(apiKey = "com.laike.payment.wechat.v2.pay",
            login = true, module = AppConst.MODULE_NAME, version = "1.0.0")
    @Transactional
    @Override
    public Map<String, String> pay(PaymentParams params) throws LaiKeAPIException {
        Map<String,String> payData = new HashMap<>();
        try {
            User user = null;
            RedisUtil redisUtil = SpringHelper.getBeanInfo(RedisUtil.class);
            user = RedisDataTool.getRedisUserCache(params.getAccessId(), redisUtil, true);
            String openid = openUserService.selectOpenidByUser(user, params.getStoreId());
            if(StringUtils.isBlank(openid)){
                throw new LaiKeAPIException("用户没有openid");
            }
            //母单号
            //获取订单信息
            OrderParentService orderParentService = SpringHelper.getBeanInfo(OrderParentService.class);
            OrderParent orderParent = orderParentService.getOrderParent(params.getOrderParentNo());
            Integer status = orderParent.getStatus();
            if(!OrderParentStatusEnum.WAIT_PAY.getCode().equals(status)){
                throw new LaiKeAPIException(ERROR_CODE_YFKQECFZF, "请勿重复支付!", "pay");
            }
            WechatConfigInfo config = getWechatConfigInfo(params);
            WXPay wxpay = new WXPay(config);
            logger.info("微信支付配置:{}",wxpay.toString());
            //查看微信订单信息（返回结果示例）
            /*<xml>
            <return_code><![CDATA[SUCCESS]]></return_code>
            <return_msg><![CDATA[OK]]></return_msg>
            <result_code><![CDATA[SUCCESS]]></result_code>
            <mch_id><![CDATA[1516978921]]></mch_id>
            <appid><![CDATA[wx441f3b338ac30350]]></appid>
            <device_info><![CDATA[]]></device_info>
            <trade_state><![CDATA[NOTPAY]]></trade_state>
            <total_fee>1</total_fee>
            <out_trade_no><![CDATA[PS230911142035506610]]></out_trade_no>
            <trade_state_desc><![CDATA[订单未支付]]></trade_state_desc>
            <nonce_str><![CDATA[VuiOJC5YH94H861V]]></nonce_str>
            <sign><![CDATA[E572BB4FCB140458A2720E1F5317621B]]></sign>
            </xml>*/
            Map<String, String> queryMap = Maps.newHashMap();
            String payOrderNo = createPayOrderNo();
            orderParent.setPayType(PayTypeEnum.WECHAT_PAY.getCode());
            orderParent.setPayOrderNo(payOrderNo);
            orderParentService.updateByOrderParentNo(orderParent.getOrderParentNo(),orderParent);
            queryMap.put("appid", config.getAppID());
            queryMap.put("mch_id", config.getMchID());
            queryMap.put("out_trade_no", orderParent.getPayOrderNo());
            queryMap.put("nonce_str", String.valueOf(System.currentTimeMillis()));
            logger.info("签名参数", JSON.toJSONString(queryMap));
            String querySign = WXPayUtil.generateSignature(queryMap, config.getKey(), WXPayConstants.SignType.MD5);
            queryMap.put("sign", querySign);
            Map<String, String> map = wxpay.orderQuery(queryMap);
            //查看订单支付前的状态
            logger.info("支付前订单号[" + orderParent.getOrderParentNo() + "],支付订单号[" + orderParent.getOrderParentNo() + "] 微信返回的状态结果：", JSON.toJSONString(map));
            if ("SUCCESS".equals(MapUtils.getString(map, "result_code")) && !"NOTPAY".equals(MapUtils.getString(map, "trade_state"))) {
                //没有支付的情况下更换支付订单号，重新拉支付
                payOrderNo = createPayOrderNo();
                orderParent.setPayOrderNo(payOrderNo);
                orderParentService.updateByOrderParentNo(orderParent.getOrderParentNo(),orderParent);
            } else if ("SUCCESS".equals(MapUtils.getString(map, "result_code")) && "SUCCESS".equals(MapUtils.getString(map, "trade_state"))) {
                //重复支付问题
                throw new LaiKeAPIException(ERROR_CODE_YFKQECFZF, "请勿重复支付!", "pay");
            }
            Map<String, String> data = Maps.newHashMap();
            data.put("body", "采购商品");
            data.put("out_trade_no", orderParent.getPayOrderNo());
            data.put("device_info", "");
            data.put("fee_type", "CNY");
            data.put("total_fee", String.valueOf(orderParent.getPayPrice()));
            //获取ip地址
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            data.put("spbill_create_ip", IpUtil.getIpAddr(request));
            data.put("notify_url", config.getNotifyUrl());
            //支付类型
            String payClass = params.getPayType();
            String appId = config.getAppID();
            String appSecret = config.getAppSecreKey();
            switch (payClass) {
                case ORDERPAYTYPE_MINI_WECHAT:
                    data.put("trade_type", "JSAPI");
                    data.put("openid", openid);
                    break;
                case ORDERPAYTYPE_JSAPI_WECHAT:
                case ORDERPAYTYPE_PC_WECHAT:
                case ORDERPAYTYPE_H5_WECHAT:
                default:
                    data.put("trade_type", "APP");
                    break;
            }
            logger.info("微信支付请求参数{}", data);
            Map<String, String> payResult = wxpay.unifiedOrder(data);
            logger.info("微信支付 类型：{},结果结果:{}", payClass, JSONObject.toJSONString(payResult));
            String resultCode = MapUtils.getString(payResult, "result_code");
            String returnCode = MapUtils.getString(payResult, "return_code");
            if ("SUCCESS".equalsIgnoreCase(resultCode) && "SUCCESS".equalsIgnoreCase(returnCode)) {
                String time = String.valueOf((System.currentTimeMillis() / 1000));
                switch (payClass) {
                    case ORDERPAYTYPE_MINI_WECHAT:
                        Map<String, String> tmp = new HashMap<>();
                        tmp.put("appId", MapUtils.getString(payResult, "appid"));
                        tmp.put("nonceStr", MapUtils.getString(payResult, "nonce_str"));
                        tmp.put("signType", "MD5");
                        tmp.put("package", "prepay_id=" + MapUtils.getString(payResult, "prepay_id"));
                        tmp.put("timeStamp", time);
                        String sign = WXPayUtil.generateSignature(tmp, config.getKey(), WXPayConstants.SignType.MD5);
                        payData.put("timeStamp", time);
                        payData.put("state", String.valueOf(1));
                        payData.put("appid", MapUtils.getString(payResult, "appid"));
                        payData.put("nonceStr", MapUtils.getString(payResult, "nonce_str"));
                        payData.put("signType", "MD5");
                        payData.put("package", "prepay_id=" + MapUtils.getString(payResult, "prepay_id"));
                        payData.put("paySign", sign);
                        payData.put("out_trade_no", orderParent.getPayOrderNo());
                        break;
                    case ORDERPAYTYPE_PC_WECHAT:
                    case ORDERPAYTYPE_APP_WECHAT:
                    case ORDERPAYTYPE_JSAPI_WECHAT:
                        break;
//                    case ORDERPAYTYPE_H5_WECHAT:
//                        StringBuilder sb = new StringBuilder(MapUtils.getString(payResult, "mweb_url"));
//                        logger.error("微信mweb_url支付跳转链接-----------{}", sb);
//                        String h5Url = getH5Url(orderModel.getStore_id()) + "pages/pay/payResult?sNo=" + orderModel.getReal_sno() + "&payment_money=" + orderModel.getZ_price() + "&isH5=true";
//                        String gbk = URLEncoder.encode(h5Url, "GBK");
//                        logger.error("url编码后-------------{}", sb + "&redirect_url=" + gbk);
//                        payData.put("url", sb + "&redirect_url=" + gbk);
////                        payData.put("url", sb.toString());
//                        payData.put("pay_type", payClass);
//                        payData.put("prepayid", MapUtils.getString(payResult, "prepay_id"));
//                        break;
                    default:
                        break;
                }
                logger.error("============================================微信唤醒支付成功");
                return payData;

            } else {
                throw new LaiKeAPIException(ErrorCode.BizErrorCode.API_OPERATION_FAILED, "微信支付失败", "wechatJsapiPay");
//                resultMap.put("message", "支付失败");
//                resultMap.put("code", 500);
//                resultMap.put("message", "支付失败");
            }

        } catch (LaiKeAPIException l) {
            logger.error("微信支付失败", l);
            throw l;
        } catch (Exception e) {
            logger.error("微信支付 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.API_OPERATION_FAILED, "微信支付失败", "wechatJsapiPay");
        }
    }

    /**
     * 获取微信支付配置
     *
     * @param params
     * @return
     * @throws Exception
     */
    private WechatConfigInfo getWechatConfigInfo(PaymentParams params) throws Exception {
        //微信app支付 默认app支付
        String className = params.getPayType();
        int storeId = params.getStoreId();
        String paymentJson = paymentConfigModelMapper.getPaymentConfigInfo(storeId, className);
        paymentJson = URLDecoder.decode(paymentJson, GloabConst.Chartset.UTF_8);
        logger.info(className + "支付配置信息：" + paymentJson);
        JSONObject payJson = JSONObject.parseObject(paymentJson);
        String appID = payJson.getString("appid");
        logger.info("appID:{}", appID);
        String mchID = payJson.getString("mch_id");
        logger.info("mchID:{}", mchID);
        String key = payJson.getString("mch_key");
        logger.info("key:{}", key);
//        String certPath = payJson.getString("cert_p12");
//        String certPath = "C:/Users/Administrator/Desktop/WeChatPay/lkt_cert/apiclient_cert.p12";
//        logger.info("certPath:{}", certPath);
        String notifyUrl = payJson.getString("notify_url");
        logger.info("notifyUrl:{}", notifyUrl);
        String appSecreKey = payJson.getString("appsecret");
        logger.info("appSecreKey:{}", appSecreKey);
        return new WechatConfigInfo(appID, mchID, key, notifyUrl, appSecreKey);
    }

    //创建支付订单号
    public String createPayOrderNo() {
        try {
            StringBuilder payOrderNo = new StringBuilder();
            Random random = new Random();
            payOrderNo.append(FastDateFormat.getInstance(GloabConst.TimePattern.YMDHMS2).format(new Date())).append(random.nextInt(9))
                    .append(random.nextInt(9)).append(random.nextInt(9)).append(random.nextInt(9))
                    .append(random.nextInt(9)).append(random.nextInt(9));
            OrderParent orderParent = new OrderParent();
            orderParent.setPayOrderNo(payOrderNo.toString());
            LambdaQueryWrapper<OrderParent> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderParent::getPayOrderNo,payOrderNo);
            orderParent = orderParentMapper.selectOne(queryWrapper);
            if(orderParent == null){
                return payOrderNo.toString();
            }else{
                return createPayOrderNo();
            }
        } catch (Exception e) {
            logger.error("创建订单号 异常", e);
            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CJDDHSB, "创建订单号失败", "createOrderNo");
        }
    }

    @Override
    @Transactional
    public String weChatNotifyV2(HttpServletRequest request) throws LaiKeAPIException{
        try {
            /**微信返回的请求体*/
            Map params = Maps.newHashMap();
            String notifyXml = WechatPayUtils.getRequestBody(request);
            logger.info("微信回调结果：{}", notifyXml);
            String weChatXml = request.getParameter("weChat_xml");
            logger.info(weChatXml);
            if (StringUtils.isEmpty(weChatXml) && !StringUtils.isEmpty(notifyXml)) {
                weChatXml = notifyXml;
            }
            /**
             * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
             */
            String decode = URLDecoder.decode(weChatXml,"UTF-8");
            String regex = "<xml>(.*?)</xml>";
            Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
            Matcher matcher = pattern.matcher(decode);
            String xmlContent = "";
            if (matcher.find()) {
                xmlContent = matcher.group(0);
            }
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xmlContent);
            String returnCode = MapUtils.getString(notifyMap, "return_code");
            String resultCode = MapUtils.getString(notifyMap, "result_code");
            String returnMsg = MapUtils.getString(notifyMap, "return_msg");
            if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
                String payNo = MapUtils.getString(notifyMap, "out_trade_no");
                params.put("appid", MapUtils.getString(notifyMap, "appid"));
                params.put("mchID", MapUtils.getString(notifyMap, "mch_id"));
                params.put("payNo", payNo);
                LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
                OrderParent orderParent = orderParentMapper.selectOne(wrapper.eq(OrderParent::getPayOrderNo, payNo));
                Integer status = orderParent.getStatus();
                if(!OrderParentStatusEnum.WAIT_PAY.getCode().equals(status)){
                    throw new LaiKeAPIException(ERRCODE_CALLBACKPROCESSED,"订单回调已处理,勿重复处理");
                }
                PaymentParams paymentParams = new PaymentParams();
                paymentParams.setStoreId(orderParent.getStoreId());
                paymentParams.setPayType(ORDERPAYTYPE_MINI_WECHAT);
                WechatConfigInfo wechatConfigInfo = getWechatConfigInfo(paymentParams);
                params.put("storeId",orderParent.getStoreId());
                params.put("wechatConfig",wechatConfigInfo);
                //不存在的情况直接返回错误
                if (StringUtils.isBlank(wechatConfigInfo.getKey())) {
                    logger.info("微信v2回调失败:{}", wechatConfigInfo);
                }
                params.put("key", wechatConfigInfo.getKey());
                logger.info("key:{}", wechatConfigInfo.getKey());
                params.put("notifyData", xmlContent);
                Map map = payBack(params);
                logger.info("微信v2回调成功 处理结果：{}", map);
                return WXPayConstants.SUCCESS;
            } else {
                logger.info("微信v2回调失败2:{}", returnMsg);
                return WXPayConstants.FAIL;
            }
        } catch (Exception e) {
            logger.error("微信v2回调失败", e);
            return WXPayConstants.FAIL;
        }
    }

    @Transactional
    @Override
    public Map<String, Object> payBack(Map params) throws LaiKeAPIException {
        Map resultMap = Maps.newHashMap();
        try {
            int storeId = MapUtils.getInteger(params, "storeId");
            String notifyData = MapUtils.getString(params, "notifyData");
            WechatConfigInfo wechatConfig = (WechatConfigInfo) params.get("wechatConfig");
            WXPay wxpay = new WXPay(wechatConfig);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);
            logger.info("回调notifyMap-{}", JSONObject.toJSON(notifyMap));
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                logger.info("回调notifyMap-{}", JSONObject.toJSON(notifyMap));
                String payOrderNo = DataUtils.getStringVal(params, "payNo");
                //要更新子单已经订单子项
                BalancePayServiceImpl balancePayService = SpringHelper.getBeanInfo(BalancePayServiceImpl.class);
                Date now = new Date();
                LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
                OrderParent updateOrderParent = orderParentMapper.selectOne(wrapper.eq(OrderParent::getPayOrderNo, payOrderNo));
                balancePayService.updateOrderAndDetail(updateOrderParent.getUserId(), now,updateOrderParent,updateOrderParent.getPayType());
                updateOrderParent.setStatus(OrderParentStatusEnum.WAIT_SEND.getCode());
                orderParentMessageService.addOrderParentMessageAndPhoto(updateOrderParent.getUserId(),storeId, OrderParentMessageType.ORDER_PAY_SUCCESS.getCode(), updateOrderParent.getOrderParentNo(), OrderParentStatusEnum.WAIT_SEND.getCode(),"支付成功 支付方式: 微信支付",null);
                //更新母订单
                orderParentService.updateById(updateOrderParent);
                logger.info("回调订单处理成功 母单号:{}",updateOrderParent.getOrderParentNo());
            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                logger.error("微信支付支付回调失败：签名错误");
                throw new LaiKeAPIException(API_OPERATION_FAILED, "微信回调失败", "payBack");
            }
        } catch (Exception e) {
            logger.error("微信回调失败", e);
            throw new LaiKeAPIException(API_OPERATION_FAILED, "微信回调失败", "payBack");
        }
        return resultMap;
    }

    public static void main(String[] args) throws Exception {
//        String message = "%3Cxml%3E%3Cappid%3E%3C%21%5BCDATA%5Bwx6d9d2270fbd23f4f%5D%5D%3E%3C%2Fappid%3E%3Cbank_type%3E%3C%21%5BCDATA%5BOTHERS%5D%5D%3E%3C%2Fbank_type%3E%3Ccash_fee%3E%3C%21%5BCDATA%5B1%5D%5D%3E%3C%2Fcash_fee%3E%3Cfee_type%3E%3C%21%5BCDATA%5BCNY%5D%5D%3E%3C%2Ffee_type%3E%3Cis_subscribe%3E%3C%21%5BCDATA%5BN%5D%5D%3E%3C%2Fis_subscribe%3E%3Cmch_id%3E%3C%21%5BCDATA%5B1704057973%5D%5D%3E%3C%2Fmch_id%3E%3Cnonce_str%3E%3C%21%5BCDATA%5BgfoBWUkMQVD4D74gZKg5yc22x79QxnZs%5D%5D%3E%3C%2Fnonce_str%3E%3Copenid%3E%3C%21%5BCDATA%5Bopt6f7ahUpU2uhPdOeugpdi_eSEs%5D%5D%3E%3C%2Fopenid%3E%3Cout_trade_no%3E%3C%21%5BCDATA%5B250122135243633602%5D%5D%3E%3C%2Fout_trade_no%3E%3Cresult_code%3E%3C%21%5BCDATA%5BSUCCESS%5D%5D%3E%3C%2Fresult_code%3E%3Creturn_code%3E%3C%21%5BCDATA%5BSUCCESS%5D%5D%3E%3C%2Freturn_code%3E%3Csign%3E%3C%21%5BCDATA%5B50F0D775030A7AE124EE3017D66111C3%5D%5D%3E%3C%2Fsign%3E%3Ctime_end%3E%3C%21%5BCDATA%5B20250122135250%5D%5D%3E%3C%2Ftime_end%3E%3Ctotal_fee%3E1%3C%2Ftotal_fee%3E%3Ctrade_type%3E%3C%21%5BCDATA%5BJSAPI%5D%5D%3E%3C%2Ftrade_type%3E%3Ctransaction_id%3E%3C%21%5BCDATA%5B4200002498202501228163896784%5D%5D%3E%3C%2Ftransaction_id%3E%3C%2Fxml%3E".trim();
        String message = "weChat_xml=%3Cxml%3E%3Cappid%3E%3C%21%5BCDATA%5Bwx6d9d2270fbd23f4f%5D%5D%3E%3C%2Fappid%3E%3Cbank_type%3E%3C%21%5BCDATA%5BOTHERS%5D%5D%3E%3C%2Fbank_type%3E%3Ccash_fee%3E%3C%21%5BCDATA%5B1%5D%5D%3E%3C%2Fcash_fee%3E%3Cfee_type%3E%3C%21%5BCDATA%5BCNY%5D%5D%3E%3C%2Ffee_type%3E%3Cis_subscribe%3E%3C%21%5BCDATA%5BN%5D%5D%3E%3C%2Fis_subscribe%3E%3Cmch_id%3E%3C%21%5BCDATA%5B1704057973%5D%5D%3E%3C%2Fmch_id%3E%3Cnonce_str%3E%3C%21%5BCDATA%5Ba88vQszTFkht6XDQBLGcBgLsvY36ATt6%5D%5D%3E%3C%2Fnonce_str%3E%3Copenid%3E%3C%21%5BCDATA%5Bopt6f7ahUpU2uhPdOeugpdi_eSEs%5D%5D%3E%3C%2Fopenid%3E%3Cout_trade_no%3E%3C%21%5BCDATA%5B250122184729183568%5D%5D%3E%3C%2Fout_trade_no%3E%3Cresult_code%3E%3C%21%5BCDATA%5BSUCCESS%5D%5D%3E%3C%2Fresult_code%3E%3Creturn_code%3E%3C%21%5BCDATA%5BSUCCESS%5D%5D%3E%3C%2Freturn_code%3E%3Csign%3E%3C%21%5BCDATA%5BC32C02FF855DAF2609833DCDFB43DE78%5D%5D%3E%3C%2Fsign%3E%3Ctime_end%3E%3C%21%5BCDATA%5B20250122184734%5D%5D%3E%3C%2Ftime_end%3E%3Ctotal_fee%3E1%3C%2Ftotal_fee%3E%3Ctrade_type%3E%3C%21%5BCDATA%5BJSAPI%5D%5D%3E%3C%2Ftrade_type%3E%3Ctransaction_id%3E%3C%21%5BCDATA%5B4200002487202501220554733939%5D%5D%3E%3C%2Ftransaction_id%3E%3C%2Fxml%3E&api=app.orderV2.weChatNotify";
        String encode = URLDecoder.decode(message, "UTF-8");
        String regex = "<xml>(.*?)</xml>";
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
        Matcher matcher = pattern.matcher(encode);
        String xmlContent = "";
        if (matcher.find()) {
            xmlContent = matcher.group(0);
            System.out.println("Extracted XML content:");
            System.out.println(xmlContent);
        } else {
            System.out.println("No XML content found within the specified tags.");
        }
        final Map<String, String> stringStringMap = XmlUtil.xmlToMap(xmlContent);

//        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
//        Document parse = documentBuilder.parse(new InputSource(new StringReader(message)));
//        int index = message.indexOf("&");
//        String substring = message.substring(0, index);
//        final String trim = substring.trim();
//        final String s = new String(trim.getBytes("gbk"), "UTF-8");
//        Map<String, String> stringStringMap = WXPayUtil.xmlToMap(message.trim());
        System.out.println();
    }

}
